﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

using ERPStore.Extensions;
using ERPStore.Web.Extensions;

namespace ERPStore.Payment.Direct.Controllers
{
	public class SandboxPaymentController: DirectPaymentController
	{
		public SandboxPaymentController(
			ERPStore.Services.ICartService cartService
			, ERPStore.Services.ISalesService salesService
			, ERPStore.Services.IAccountService accountService
			, ERPStore.Services.IEmailerService emailerService
			, Web.Services.IEmailTemplateService emailTemplateService
			, ERPStore.Services.IIncentiveService incentiveService
			, ERPStore.Services.CryptoService cryptoService
			, ERPStore.Services.IFraudService fraudService
			, Services.SandBoxPaymentService paymentService
			, ERPStore.Services.IOffersService offerService
			)
			: base(cartService, salesService, accountService, emailerService, emailTemplateService, incentiveService, cryptoService, fraudService, offerService)
		{
			this.PaymentService = paymentService;
		}

		protected Services.SandBoxPaymentService PaymentService { get; private set; }

		protected override string FinalizeViewName
		{
			get
			{
				return PaymentService.FinalizedViewName;
			}
		}

		protected override string PaymentName
		{
			get
			{
				return PaymentService.Name;
			}
		}

		[AcceptVerbs(HttpVerbs.Post)]
		[global::ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		[global::ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		public override ActionResult PaymentConfirmation(string condition)
		{
			bool confirmation = (condition == "on");

			var cart = CartService.GetCurrentCart(User);
			cart.AcceptCondition = true;
			bool isNewCustomer = false;
			string password = string.Empty;
			var user = User.CurrentUser;

			if (user == null)
			{
				var registration = AccountService.GetRegistrationUser(User.VisitorId);
				if (registration == null)
				{
					return RedirectToERPStoreRoute(Web.Routing.ERPStoreRoutes.CHECKOUT);
				}
				var registrationUser = AccountService.CreateUserFromRegistration(registration);
				cart.BillingAddress = registrationUser.DefaultAddress;
				cart.DeliveryAddress = registrationUser.LastDeliveredAddress;

				password = registration.Password;
				if (registration.IsSameBillingAddress)
				{
					registration.BillingAddressCity = registration.ShippingAddressCity;
					registration.BillingAddressCountryId = registration.ShippingAddressCountryId;
					registration.BillingAddressRecipientName = registration.ShippingAddressRecipientName;
					registration.BillingAddressRegion = registration.ShippingAddressRegion;
					registration.BillingAddressStreet = registration.ShippingAddressStreet;
					registration.BillingAddressZipCode = registration.ShippingAddressZipCode;
				}

				try
				{
					user = AccountService.RegisterUser(registration);
					Response.AddAuthenticatedCookie(user.Id, true);
					isNewCustomer = true;
				}
				catch (Exception ex)
				{
					LogError(Logger, ex);
					ModelState.AddModelError("_FORM", "Un problème technique empèche la creation de votre commande, veuillez reessayer ultérieurement");
				}

				// Affectation de l'adresse de livraison
				cart.DeliveryAddress = new ERPStore.Models.Address();
				cart.DeliveryAddress.City = registration.ShippingAddressCity;
				cart.DeliveryAddress.CountryId = registration.ShippingAddressCountryId;
				cart.DeliveryAddress.RecipientName = registration.ShippingAddressRecipientName;
				cart.DeliveryAddress.Region = registration.ShippingAddressRegion;
				cart.DeliveryAddress.Street = registration.ShippingAddressStreet;
				cart.DeliveryAddress.ZipCode = registration.ShippingAddressZipCode;

				// Affectation de l'adresse de facturation
				cart.BillingAddress = user.DefaultAddress;
				cart.CustomerId = user.Id;
			}


			// Préparation d'un paramètre encrypté
			var subject = new
			{
				OrderCode = cart.Code,
				DocumentType = "3",
				ExpirationDate = DateTime.Now.AddDays(1),
				IsNewCustomer = isNewCustomer,
				Password = password,
				CartCode = cart.Code,
			};
			var key = CryptoService.Encrypt(subject);

			return RedirectToERPStoreRoute(PaymentService.FinalizedRouteName, new { key = key });
		}

		[Authorize(Roles = "customer")]
		[ERPStore.Web.Controllers.ActionFilters.ZeroCacheActionFilter]
		[ERPStore.Web.Controllers.ActionFilters.TrackerActionFilter]
		public override System.Web.Mvc.ActionResult Finalized(string key)
		{
			var subject = new
			{
				Code = string.Empty,
				DocumentType = string.Empty,
				ExpirationDate = DateTime.MinValue,
				IsNewCustomer = false,
				Password = string.Empty,
				CartCode = string.Empty,
			};

			var order = new ERPStore.Models.Order();

			List<object> result = null;
			try
			{
				result = CryptoService.Decrypt(key, subject);
			}
			catch
			{
				return RedirectToERPStoreRoute(Web.Routing.ERPStoreRoutes.HOME);
			}
			var code = Convert.ToString(result[0]);
			var documentType = Convert.ToString(result[1]);
			var expirationDate = Convert.ToDateTime(result[2]);
			var isNewCustomer = Convert.ToBoolean(result[3]);
			var password = Convert.ToString(result[4]);
			var cartCode = Convert.ToString(result[5]);

			var cart = CartService.GetCartByCode(code);

			cart.State = ERPStore.Models.CartState.ConvertedToOrder;

			CartService.Save(cart);

			order.Code = code;
			order.Items = new ERPStore.Models.LazyList<ERPStore.Models.ISaleItem>(() => new List<ERPStore.Models.ISaleItem>());
			foreach (var item in cart.Items)
			{
				order.Items.Add(new ERPStore.Models.OrderItem()
				{
					Product = item.Product,
					Designation = item.Product.Title,
					ProductCode = item.Product.Code,
					Quantity = item.Quantity,
					SalePrice = item.SalePrice,
					SaleUnitValue = item.SaleUnitValue,
					TaxRate = item.CatalogPrice.TaxRate,
				});
			}

			order.GrandTaxTotal = cart.GrandTaxTotal;
			order.GrandTotalWithTax = cart.GrandTotalWithTax;
			order.GrandTotal = cart.GrandTotal;

			ViewBag.CartCode = cartCode;
			ViewData.Model = order;

			var viewName = string.Format("~/views/checkout/{0}", PaymentService.FinalizedViewName);
			return View(viewName);
		}
	}
}
